function res = GroupCharacterization(obj, varargin)
    L = log4m.getLogger;
    
    p=inputParser;
    p.addRequired('Temperature', @(x) x>0);
    p.addRequired('PumpPower', @(x) x>0);
    p.addRequired('ProbePower', @(x) x>0);
    p.addRequired('PumpFrequency', @(x) x>0);
    p.addRequired('ProbeFrequency', @(x) x>0);
    p.addParameter('AOMVoltage', 1.0);
    p.addParameter('EaterVoltage', 0.4);
    p.addParameter('initialField', 6.0, @(x) x>0);
    p.addParameter('isFixBz0', false, @islogical);
    p.addParameter('initialBx0', 0.04);
    p.addParameter('initialBy0', -1.3);
    p.addParameter('amplitudeTransX', 0.01, @(x) x>0 && x<1);
    p.addParameter('amplitudeTransY', 0.05, @(x) x>0 && x<1);
    p.addParameter('Xe129DrivingAmplitude', 0.016, @(x) x>0);
    p.addParameter('Xe131DrivingAmplitude', 0.050, @(x) x>0);
    p.addParameter('Xe129Coeff', 253.880/5.939);
    p.addParameter('sign129', -1, @(x) ismember(x, [-1 1]));
    p.addParameter('sign131', 1, @(x) ismember(x, [-1 1]));
    p.addParameter('EstXe129T2', 10.0);
    p.addParameter('EstXe131T2', 20.0);
    p.addParameter('EstXe129T1', 100.0);
    p.addParameter('EstXe131T1', 30.0);
    p.addParameter('description', '', @ischar);
    p.parse(varargin{:});
    %%
    descriptionStr = sprintf('Temp%3.1fdegC_AOM%4.3fV_EATER%4.3fV_%s',p.Results.Temperature, p.Results.AOMVoltage, p.Results.EaterVoltage, p.Results.description);
    
    getReporter;
    rpt.NewGroup(sprintf('Gyroscope Characterization Group, T=%d degC, PumpPower=%5.3fmW, ProbePower=%5.3fmW', p.Results.Temperature, p.Results.PumpPower,p.Results.ProbePower));
    rpt.MainText('In this group, we perform a set of measurements to characterize the parametric magnetometer and the nmr gyroscope.');
    rpt.TextEnter();
    
    dataCell = {'pump power (mW)',                     'pump freq (THz)',                        'probe power (mW)',                     'probe freq (THz)',                         'cell temp (degC)'; ...
                sprintf('%8.5f', p.Results.PumpPower), sprintf('%8.5f', p.Results.PumpFrequency), sprintf('%3.2f', p.Results.ProbePower), sprintf('%8.5f', p.Results.ProbeFrequency), sprintf('%3.1f', p.Results.Temperature)};
    rpt.AppendTable(dataCell, 'Unchanged Parameters.');
    res.condition = dataCell;
    %%    
    obj.initialize; pause(1.0);
    obj.aom.setDC(p.Results.AOMVoltage); pause(1.0);    
    obj.eater.setDC(p.Results.EaterVoltage); pause(1.0);
    
    res.MainField = obj.GetMainField('initialField', p.Results.initialField, 'isFixBz0', p.Results.isFixBz0, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.WorkingPoint0 = obj.GetWorkingPoint('initialBx0', p.Results.initialBx0, 'initialBy0', p.Results.initialBy0, ...
                                           'amplitudeTransX', p.Results.amplitudeTransX, 'amplitudeTransY', p.Results.amplitudeTransY, 'description', [descriptionStr '_Pre'], 'isReport', true); pause(1.0);
    res.WorkingPoint = obj.GetWorkingPoint('initialBx0', res.WorkingPoint0.biasX, 'initialBy0', res.WorkingPoint0.biasY, ...
                                           'amplitudeTransX', p.Results.amplitudeTransX, 'amplitudeTransY', p.Results.amplitudeTransY, 'description', descriptionStr, 'isReport', true); pause(1.0);
    obj.LockTransverseField(); pause(1.0);
    res.MagnetometerSensitivity = obj.GetMagnetometerSensitivity('description', descriptionStr, 'isReport', true); pause(1.0);
    res.MagnetometerBandwidth = obj.GetMagnetometerBandwidth('description', descriptionStr, 'isReport', true); pause(1.0);
    
    guessFreq129 = obj.SystemInfo.MainField.bz0*p.Results.Xe129Coeff;  guessFreq131 = guessFreq129/3.37340;
    res.FIDXe129Signal0 = obj.GetXe129FID(3.0*p.Results.EstXe129T2, 'guessFrequency', guessFreq129, 'description', [descriptionStr '_Pre'], 'isReport', true); pause(1.0);
    res.FIDXe129Signal  = obj.GetXe129FID(5.0+5.0*res.FIDXe129Signal0.T2, 'guessFrequency', res.FIDXe129Signal0.f129, 'description', descriptionStr, 'isReport', true); pause(1.0);
    res.FIDXe131Signal0 = obj.GetXe131FID(3.0*p.Results.EstXe131T2, 'guessFrequency', guessFreq131, 'description', [descriptionStr '_Pre'], 'isReport', true); pause(1.0);
    res.FIDXe131Signal  = obj.GetXe131FID(5.0+5.0*res.FIDXe131Signal0.T2, 'guessFrequency',  res.FIDXe131Signal0.f131, 'description', descriptionStr, 'isReport', true); pause(1.0);

%     drvTime = max([3.0*obj.SystemInfo.Xe129FID.T2, 3.0*obj.SystemInfo.Xe131FID.T2, 120]);
%     res.XeDriving = obj.GetXeDriving('recordTime', drvTime, 'amplitude129',p.Results.Xe129DrivingAmplitude, 'amplitude131', p.Results.Xe131DrivingAmplitude,...
%                                      'description', descriptionStr, 'isReport', true); pause(1.0);
%     obj.LockXe129();
%     L.info('NMRGyroscope::GroupCharacterization', sprintf('Xe129 Locked. Waiting [%d s] for steady state...', drvTime) ); pause( drvTime );
%     res.XePhaseNoiseLock = obj.GetXePhaseNoise('average', 400, 'description', [descriptionStr '_CloseLoop'], 'isReport', true); pause(1.0);

%     tWait = max([3.0*obj.SystemInfo.Xe129FID.T2, 3.0*obj.SystemInfo.Xe131FID.T2, 120]);
%     obj.by129.disableDriver(); obj.by131.disableDriver();
%     L.info('NMRGyroscope::GroupCharacterization', sprintf('NMR Driving disabled. Waiting for nuclear spin pumping to steady state [%d s]...', tWait) );  pause( tWait );

    drvTime129 = max([6.0*obj.SystemInfo.Xe129FID.T2, 30]); drvTime131 = max([6.0*obj.SystemInfo.Xe131FID.T2, 30]);
    decayTime129 = max([3.0*p.Results.EstXe129T1, 180]); decayTime131 = max([3.0*p.Results.EstXe131T1, 180]);
    res.Xe129T1Rho = obj.GetXe129T1Rho(drvTime129, decayTime129, 'sign', p.Results.sign129, 'description', descriptionStr, 'isReport', true); 
    res.Xe131T1Rho = obj.GetXe131T1Rho(drvTime131, decayTime131, 'sign', p.Results.sign131, 'description', descriptionStr, 'isReport', true); pause(1.0);
    
    tRelax = max([5.0*obj.SystemInfo.Xe129T1Rho.PumpTime, 5.0*obj.SystemInfo.Xe131T1Rho.PumpTime, 120]);
    res.XeRelaxation = obj.GetXeRelaxation(tRelax, 'description', descriptionStr, 'isReport', true); pause(1.0);
    
    obj.aom.setDC(p.Results.AOMVoltage);
    %%
    getSession;
    sess.addData('MeasurementPackage', res, descriptionStr);
end

